﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// 对Animator进行拓展
/// </summary>
public static class AnimatorExtension
{
    /// <summary>
    /// 要设置的动画信息
    /// </summary>
    static string[] AnimationInfo = new string[3];
    #region Animator
    private static Dictionary<Animator, bool> bool_Animator = new Dictionary<Animator, bool>();
    /// <summary>
    /// 探测动画控制器
    /// </summary>
    /// <param name="ani"></param>
    /// <param name="layerIndex"></param>
    /// <param name="stateName"></param>
    /// <param name="OnStart"></param>
    /// <param name="OnUpdate"></param>
    /// <param name="OnEnd"></param>
    public static void DetectionAnimator(this Animator ani, int layerIndex, string stateName, UnityAction OnStart, UnityAction OnUpdate, UnityAction OnEnd)
    {
        if (!bool_Animator.ContainsKey(ani))
        {
            bool_Animator.Add(ani, false);
        }
        if (!bool_Animator[ani])
        {
            if (ani.GetCurrentAnimatorStateInfo(layerIndex).IsName(stateName))
            {
                bool_Animator[ani] = true;
                OnStart();
            }
        }
        else
        {
            if (ani.GetCurrentAnimatorStateInfo(layerIndex).IsName(stateName))
            {
                OnUpdate();
            }
            else
            {
                bool_Animator[ani] = false;
                OnEnd();
            }
        }
    }
    public static void ResetBool_Animator()
    {
        if (bool_Animator != null)
            bool_Animator.Clear();
    }
    /// <summary>
    /// 给动画添加新的事件
    /// </summary>
    /// <param name="_Animator"> 人物的状态机</param>
    /// <param name="_ClipName">动画的名称</param>
    /// <param name="_EventFunctionName">时间/秒</param>
    /// <param name="_time"></param>
    /// <param name="parameter"></param>
    public static void AddAnimationEvent(this Animator _Animator, string _ClipName, string _EventFunctionName, float _time = 1, bool parameter = true)
    {
        AnimationClip[] _clips = _Animator.runtimeAnimatorController.animationClips;
        for (int i = 0; i < _clips.Length; i++)
        {
            if (_clips[i].name == _ClipName)
            {
                AnimationEvent _event = new AnimationEvent();
                _event.functionName = _EventFunctionName;
                if (parameter)
                {
                    _event.stringParameter = _ClipName;
                }

                _event.time =(_time >1 || _time < 0) ? _clips[i].length : _clips[i].length* _time;
                _clips[i].AddEvent(_event);
                break;
            }
        }
        _Animator.Rebind();
    }
    /// <summary>
    /// 是否存在某个动画
    /// </summary>
    /// <param name="_Animator"></param>
    /// <param name="_ClipName"></param>
    /// <returns></returns>
    public static bool ContinsAnimation(this Animator _Animator, string _ClipName)
    {
        AnimationClip[] _clips = _Animator.runtimeAnimatorController.animationClips;
        for (int i = 0; i < _clips.Length; i++)
        {
            if (_clips[i].name == _ClipName)
            {
                return true;
            }
        }
        return false;
    }

    public static void AddAnimationEvent(this Animator _Animator, string[] _ClipName, string _EventFunctionName, float _time = 1, bool parameter = true)
    {
        AnimationClip[] _clips = _Animator.runtimeAnimatorController.animationClips;
       
        for (int i = 0; i < _clips.Length; i++)
        {
           
            if (_clips[i].name.Contains( _ClipName))
            {
                AnimationEvent _event = new AnimationEvent();
                _event.functionName = _EventFunctionName;
                if (parameter)
                {
                    _event.stringParameter = _clips[i].name;
                  
                }

                _event.time = (_time > 1 || _time < 0) ? _clips[i].length : _clips[i].length * _time;
                _clips[i].AddEvent(_event);
            }
        }
        
        _Animator.Rebind();
    }
    /// <summary>
    /// 重置某个动画
    /// </summary>
    /// <param name="_Animator">动画控制器</param>
    /// <param name="_ClipName">动画名称</param>
    public static void ResetAnimation(this Animator _Animator, string _ClipName)
    {
        if(_Animator.ContinsAnimation(_ClipName))
        {
            _Animator.Play(_ClipName, -1, 0f);
            _Animator.Update(0f);
        }
    }

    public static void ResetAnimation(this Animator _Animator, string _ClipName,int layer)
    {
        if (_Animator.ContinsAnimation(_ClipName))
        {
            _Animator.Play(_ClipName, layer, 0f);
            _Animator.Update(0f);
        }
    }

    /// <summary>
    /// 设置动画信息
    /// </summary>
    /// <param name="_Animator"></param>
    /// <param name="AnimationInfos"></param>
    public static void SetAnimatorInfo(this Animator _Animator,string AnimationInfos)
    {
        AnimationInfo = AnimationInfos.Split('-');
        switch (AnimationInfo[0])
        {
            case "Bool":
                _Animator.SetBool(AnimationInfo[1], AnimationInfo[2].Contains("True"));
                break;
            case "Float":
               
                _Animator.SetFloat(AnimationInfo[1], AnimationInfo[2].ToFloat());
                break;
            case "Int":
                //int temp = AnimationInfo[2].ToInt() / 10 - 1;
                //if (temp != -1 && !(AnimationInfo[2].ToInt() >= 10 && AnimationInfo[2].ToInt() <= 12))
                //{
                //    if (_Animator.GetInteger("WeaponType") == temp)
                //        _Animator.SetInteger(AnimationInfo[1], (AnimationInfo[2].ToInt() % 10));
                //}
                //else
                //{
                    _Animator.SetInteger(AnimationInfo[1], AnimationInfo[2].ToInt());
                //}
                //_Animator.SetInteger(AnimationInfo[1], AnimationInfo[2].ToInt());
                break;
            case "Play":
                _Animator.Play(AnimationInfo[1]/*, AnimationInfo[2].ToInt()*/);
                break;
            case "Trigger":
                _Animator.SetTrigger(AnimationInfo[1]);
                break;
            default:
                if (!_Animator.GetCurrentAnimatorClipInfo(0)[0].clip.name.Contains(AnimationInfos))
                {
                    _Animator.Play(AnimationInfos/*, AnimationInfo[2].ToInt()*/);
                }
                else
                {
                   if(AnimationInfos.AllNumber())
                    {
                        _Animator.speed = float.Parse(AnimationInfos);
                    }
                }
                  
                break;
        }
    }



    /// <summary>
    /// 指示器
    /// </summary>
    /// <param name="ani"></param>
    /// <param name="layerIndex"></param>
    /// <param name="stateName"></param>
    /// <param name="OnStart"></param>
    /// <param name="OnUpdate"></param>
    /// <param name="OnEnd"></param>
    /// <returns></returns>
    public static IEnumerator IEDetectionAnimator(this Animator ani, int layerIndex, string stateName, UnityAction OnStart, UnityAction OnUpdate, UnityAction OnEnd)
    {
        while (!ani.GetCurrentAnimatorStateInfo(layerIndex).IsName(stateName))
        {
            yield return null;
        }
        OnStart();
        while (ani.GetCurrentAnimatorStateInfo(layerIndex).IsName(stateName))
        {
            OnUpdate();
            yield return null;
        }
        OnEnd();
    }
    #endregion

}
